use std::{collections::HashMap, future::{ready, Future}, sync::{Arc, Mutex}, pin::Pin};

use super::{AuthInfo, AuthStore, TokenInfo};

pub struct MemoryAuthStore {
    auth_store: Arc<Mutex<HashMap<String, AuthInfo>>>,
    token_store: Arc<Mutex<HashMap<String, TokenInfo>>>,
}

impl MemoryAuthStore {
    fn remove_auth(&self, uid: &str) -> Option<AuthInfo> {
        let mut r = self.auth_store.lock().unwrap();
        r.remove(uid)
    }
    fn set_auth(&self, uid: &str, info: AuthInfo) {
        let mut r = self.auth_store.lock().unwrap();
        r.insert(uid.to_string(), info);
    }
    fn set_token(&self, uid: &str, info: TokenInfo) {
        let mut r = self.token_store.lock().unwrap();
        r.insert(uid.to_string(), info);
    }
    fn get_token(&self, uid: &str) -> Option<TokenInfo> {
        let r = self.token_store.lock().unwrap();
        r.get(uid).cloned()
    }
}

impl MemoryAuthStore {
    pub fn new() -> Self {
        Self { 
            auth_store: Arc::new(Mutex::new(HashMap::new())),
            token_store: Arc::new(Mutex::new(HashMap::new())),
        }
    }
}

impl AuthStore for MemoryAuthStore {
    fn set_auth(&self, uid: &str, info: AuthInfo) -> Pin<Box<dyn Future<Output=()> + Send>> {
        Box::pin(ready(self.set_auth(uid, info)))
    }

    fn remove_auth(&self, uid: &str) -> Pin<Box<dyn Future<Output=Option<AuthInfo>> + Send>> {
        Box::pin(ready(self.remove_auth(uid)))
    }

    fn set_token_info(&self, uid: &str, info: TokenInfo) -> Pin<Box<dyn Future<Output=()> + Send>> {
        Box::pin(ready(self.set_token(uid, info)))
    }

    fn get_token_info(&self, uid: &str) -> Pin<Box<dyn Future<Output=Option<TokenInfo>> + Send>> {
        Box::pin(ready(self.get_token(uid)))
    }
}

/* 
#[derive(Clone)]
pub struct MemoryAuthStoreRef {
    r: Arc<MemoryAuthStore>
}

impl MemoryAuthStoreRef {
    pub fn new() -> Self {
        Self { r: Arc::new(MemoryAuthStore::new()) }
    }
}
impl AuthStore for MemoryAuthStoreRef {
    fn set_auth(&self, uid: &str, info: AuthInfo) -> Pin<Box<dyn Future<Output=()> + Send>> {
        Box::pin(ready(self.r.set_auth(uid, info)))
    }

    fn remove_auth(&self, uid: &str) -> Pin<Box<dyn Future<Output=Option<AuthInfo>> + Send>> {
        Box::pin(ready(self.r.remove_auth(uid)))
    }

    fn set_token_info(&self, uid: &str, info: TokenInfo) -> Pin<Box<dyn Future<Output=()> + Send>> {
        Box::pin(ready(self.r.set_token(uid, info)))
    }

    fn get_token_info(&self, uid: &str) -> Pin<Box<dyn Future<Output=Option<TokenInfo>> + Send>> {
        Box::pin(ready(self.r.get_token(uid)))
    }
}
*/